package server.storage;

import java.io.*;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.StringTokenizer;

public class DiskOperations {
    private DataOutputStream oos;
    private int numberOfDays;
    private String pathToDir;
    private int currentDate;
    private Calendar calendar;

    public DiskOperations(String pathToDir, int numberOfDays) throws IOException {
        this.pathToDir = pathToDir;
        this.numberOfDays = numberOfDays;
        calendar = Calendar.getInstance();
    }

    private int getCurrentDate() {
        return 1000 * calendar.get(Calendar.YEAR) + calendar.get(Calendar.DAY_OF_YEAR);
    }

    public ArrayList<String> loadAllMessages() {
        updateFileNameByDate();
        ArrayList<String> messages = new ArrayList<>();
        for(int i = numberOfDays - 1; i >= 0; i--) {
            messages.addAll(loadAllMessages(getFileName(currentDate - i)));
        }
        return messages;
    }

    private ArrayList<String> loadAllMessages(String path) {
        ArrayList<String> messages = new ArrayList<>();
        try(DataInputStream ois = new DataInputStream(new FileInputStream(new File(path)))) {
            while (ois.available() > 0) {
                messages.add(ois.readUTF());
                messages.add("\n");
            }
        } catch (IOException e) {
            System.out.println("File not found : " + path);
        }
        return messages;
    }

    public ArrayList<String> loadAllMessagesFromLobby(String lobby) {
        updateFileNameByDate();
        ArrayList<String> messages = new ArrayList<>();
        for(int i = numberOfDays - 1; i >= 0; i--) {
            messages.addAll(loadAllMessagesFromLobby((getFileName(currentDate - i)), lobby));
        }
        return messages;
    }

    private ArrayList<String> loadAllMessagesFromLobby(String path, String lobby) {
        ArrayList<String> messages = new ArrayList<>();
        try {
            try(DataInputStream ois = new DataInputStream(new FileInputStream(new File(path)))) {
                while (ois.available() > 0) {
                    String message = ois.readUTF();
                    StringTokenizer st = new StringTokenizer(message,"[");
                    st.nextToken();
                    if (st.nextToken().split("]")[0].equals(lobby)) {
                        messages.add(message);
                        messages.add("\n");
                    }
                }
            }
        } catch (IOException e) {
            System.out.println("File not found : " + path);
        }
        return messages;
    }

    public boolean saveMessage(String  message){
        updateFileNameByDate();
        try {
            oos.writeUTF(message);
            oos.flush();
            return true;
        } catch (IOException e) {
            e.printStackTrace();
            return false;
        }
    }

    private void updateFileNameByDate() {
        if(currentDate != getCurrentDate()) {
            currentDate = getCurrentDate();
            close();
            File file = new File(getFileName(currentDate));
            if (!file.exists()) {
                try {
                    file.createNewFile();
                } catch (IOException e) {
                    System.err.println("File not created;" + file.getAbsolutePath());
                }
            }
            try {
                oos = new DataOutputStream(new FileOutputStream(file, true));
            } catch (FileNotFoundException e) {
                System.err.println("File error:" + file.getAbsolutePath());
            }
            file = new File(getFileName(currentDate - numberOfDays));
            if(file.exists()) {
                file.delete();
            }
        }
    }

    private String getFileName(int date) {
        return pathToDir + "/" + date;
    }

    public void close() {
        try {
            if(oos != null) {
                oos.close();
            }
        } catch (IOException e) {
            System.err.println("File not closed");
        }
    }
}
